package com.zhongfeng.api.modules.end.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhongfeng.api.modules.end.mapper.EndMapper;
import com.zhongfeng.api.modules.end.service.EndService;
import com.zhongfeng.api.modules.end.vo.EndVo;
import com.zhongfeng.api.modules.end.vo.params.EndParams;
import com.zhongfeng.api.modules.front.mapper.FrontMapper;
import com.zhongfeng.api.modules.front.vo.FrontVo;
import com.zhongfeng.api.modules.front.vo.NumberVo;
import com.zhongfeng.api.modules.front.vo.params.FrontParams;
import com.zhongfeng.api.modules.utils.function.Check;
import com.zhongfeng.api.modules.utils.function.Transfer;
import com.zhongfeng.api.modules.utils.pojo.PageDataInfo;
import com.zhongfeng.api.modules.utils.pojo.Result;
import com.zhongfeng.api.modules.utils.service.HttpStatus;
import com.zhongfeng.api.modules.utils.service.ReturnCodes;
import com.zhongfeng.api.modules.utils.service.ReturnMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.zhongfeng.api.modules.utils.function.Check.isNumeric;

/**
 * @author blueCat
 * @date 2023/2/2 14:02
 * @motto life is a gift
 */
@Service
@Slf4j
public class EndServiceImpl implements EndService {
    @Autowired
    private EndMapper endMapper;

    @Autowired
    private FrontMapper frontMapper;

    private static Map<Integer, Integer> numberMap;

    /**
     * 查询全部下游信息
     *
     * @param params
     * @return
     */
    @Override
    public Result queryAllEnd(EndParams params) {
        Page<EndVo> page = new Page<>(params.getPageNum(), params.getPageSize());
        //默认按照公司名降序
        if (params.getOrderByColumn() == null || params.getOrderByColumn().equals("")) {
            params.setOrderByColumn("company");
            params.setIsAsc("desc");
        }
        List<EndVo> endVos = endMapper.queryAllEnd(page, params);
        //查询全部落地网关
        List<FrontVo> frontVos = frontMapper.queryAllFront(null, new FrontParams());
        Map<String, String> frontMap = new HashMap<>();
        for (FrontVo frontVo : frontVos) {
            frontMap.put(frontVo.getId(), frontVo.getCompany() + ":" + frontVo.getIp());
        }
        for (EndVo endVo : endVos) {
            //转换价格
            endVo.setPrice(Transfer.transferPrice(endVo.getPriceDouble()));
            //回填白名单数并重新排序白名单
            String whiteNumber = endVo.getWhiteNumber();
            if (whiteNumber != null && !whiteNumber.equals("")) {
                String[] split = whiteNumber.split(",");
                endVo.setWhiteCounts(split.length);
            }
            //回填对接信息
            String joint = "对接IP和端口:" + endVo.getIp() + ":2280\n"+
                    "允许时段:07:00:00 --- 23:00:00\n"+
                    "盲区:无\n"+
                    "主叫:不需要前缀\n"+
                    "被叫:11位手机号\n"+
                    "并发:1比3轮询\n"+
                    "价格:"+endVo.getPrice()+"\n"+
                    "计费精度:1000\n\n"+
                    "查费链接:http://" + endVo.getIp() + ":28080\n" +
                    "账号:" + endVo.getCompany() + "A路\n" +
                    "密码:888888\n\n"+
                    "公司禁止业务：\n" +
                    "股票，彩票，证券，基金，原油，博彩，私募，" +
                    "POS机（刷卡机），京东金融，抖音（除催收电商一律禁止），" +
                    "修复征信（减免还款等一律禁止），刷单，兼职，" +
                    "消除征信不良记录统一定性为诈骗。" +
                    "冒充银行助贷统一定性为诈骗。\n\n" +
                    "充值账号\n" +
                    "名称：深圳市众峰科技信息有限公司\n" +
                    "纳税识别号：91440300MA5FDBCT4N\n" +
                    "地址、电话：深圳市前海深港合作区前湾一路1号A栋201室（入驻深圳市前海商务秘书有限公司）19972721717\n" +
                    "开户行及账号：中信银行股份有限公司深圳福强支行8110301013300532778";
            endVo.setJoint(joint);
            //回填IP
            endVo.setIp("http://" + endVo.getIp() + ":28080");
            //回填查费信息
            String information = "查费链接:" + endVo.getIp() +
                    "\n账号:" + endVo.getCompany() +
                    "A路\n密码:888888\n\n" +
                    "充值账号\n" +
                    "名称：深圳市众峰科技信息有限公司\n" +
                    "纳税识别号：91440300MA5FDBCT4N\n" +
                    "地址、电话：深圳市前海深港合作区前湾一路1号A栋201室（入驻深圳市前海商务秘书有限公司）19972721717\n" +
                    "开户行及账号：中信银行股份有限公司深圳福强支行8110301013300532778";;
            endVo.setInformation(information);
            //回填frontId
            if (endVo.getFrontId() != null && !endVo.getFrontId().equals("")) {
                List<String> frontIdList = Transfer.transferString2(endVo.getFrontId());
                endVo.setFrontIdList(frontIdList);
                String front = "";
                for (String frontId : frontIdList) {
                    String frontVo = frontMap.get(frontId);
                    front += (frontVo + ",");
                }
                front = front.substring(0, front.length() - 1);
                endVo.setFront(front);
            }
        }
        return Result.setSuccess(HttpStatus.SUCCESS, "", new PageDataInfo(page, endVos));
    }

    /**
     * 新增下游信息
     *
     * @param params
     * @return
     */
    @Override
    public Result addEnd(EndParams params) {
        params.setFrontId(Transfer.combineList(params.getFrontIdList()));
        int i = endMapper.addEnd(params);
        if (i == 1) {
            return Result.setSuccess(HttpStatus.SUCCESS, "添加下游成功！");
        } else {
            return Result.setFail(ReturnCodes.ADD_END_FAIL, ReturnMessage.ADD_END_FAIL);
        }
    }

    /**
     * 删除下游信息
     *
     * @param id
     * @return
     */
    @Override
    public Result deleteEnd(Integer id) {
        int i = endMapper.deleteEnd(id);
        if (i == 1) {
            return Result.setSuccess(HttpStatus.SUCCESS, "删除下游成功！");
        } else {
            return Result.setFail(ReturnCodes.DELETE_END_FAIL, ReturnMessage.DELETE_END_FAIL);
        }
    }

    /**
     * 修改下游信息
     *
     * @param params
     * @return
     */
    @Override
    public Result updateEnd(EndParams params) {
        String msg = "修改对接网关成功！";
        params.setFrontId(Transfer.combineList(params.getFrontIdList()));
        //白名单去重排序
        String whiteNumber = params.getWhiteNumber();
        if (whiteNumber.equals("-1")){
            params.setWhiteNumber(null);
            whiteNumber = null;
        }
        if (whiteNumber != null && !params.equals("")) {
            msg = "白名单修改成功！";
            if (whiteNumber.contains("，")) {
                return Result.setFail(HttpStatus.FAIL, "不能使用中文逗号");
            }
            String[] split = whiteNumber.split(",");
            Set<String> set = new HashSet<>();
            //超过100个减前缀长度
            if (split.length > 100) {
                for (String s : split) {
                    set.add(s.substring(0,s.length()-1));
                }
                msg += "号码前缀减一，";
            }else {
                for (String s : split) {
                    set.add(s);
                }
            }
            List<String> list = new ArrayList<>(set);
            if (split.length > list.size()){
                msg += ("白名单数去重后减少了"+(split.length-list.size())+"个");
            }
            Collections.sort(list);
            StringJoiner sj = new StringJoiner(",");
            for (String s : list) {
                sj.add(s);
            }
            params.setWhiteNumber(sj.toString());
        }
        int i = endMapper.updateEnd(params);
        if (i == 1) {
            return Result.setSuccess(HttpStatus.SUCCESS, msg);
        } else {
            return Result.setFail(ReturnCodes.UPDATE_END_FAIL, ReturnMessage.UPDATE_END_FAIL);
        }
    }

    /**
     * 查询对接网关属性
     *
     * @return
     */
    @Override
    public Result queryEndProperty() {
        List<EndVo> endVoList = endMapper.queryEndProperty();
        return Result.setSuccess(HttpStatus.SUCCESS, "", endVoList);
    }

    /**
     * 加白
     *
     * @param params
     * @return
     */
    @Override
    public Result addWhite(EndParams params) {
        //1.查出该对接网关的全部白名单，并获取白名单前缀长度,白名单为空的话，默认长度为4
        EndVo endVo = endMapper.queryOneEnd(params.getId());
        String whiteNumber = endVo.getWhiteNumber();
        int prefixLength = 4;
        Set<String> oldList = new HashSet<>();
        if (whiteNumber != null && !whiteNumber.equals("")) {
            String[] split = whiteNumber.split(",");
            prefixLength = split[0].length();
            for (String s : split) {
                oldList.add(s);
            }
        }
        //2.处理前端传回的白名单，截取前缀并去重
        Set<String> newList = new HashSet<>();
        ByteArrayInputStream numberStream = new ByteArrayInputStream(params.getWhiteNumber().getBytes(StandardCharsets.UTF_8));
        Scanner sc = new Scanner(numberStream);
//        //查询全部x号码
//        List<String> oldXNumberList = new ArrayList<>();
//        oldXNumberList = endMapper.queryAllXNumberWithoutPage(params.getId());
//        List<String> xNumberList = new ArrayList<>();
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            if (line.contains(",")){
                String[] split = line.split(",");
                for (String s : split) {
                    if (isNumeric(s)){
//                        if (!xNumberList.contains(s) && !oldXNumberList.contains(s) && s.length() == 11){
//                            xNumberList.add(s);
//                        }
                        s = s.substring(0, prefixLength);
                        newList.add(s);
                    }
                }
                break;
            }else if (line.contains("，")){
                String[] split = line.split("，");
                for (String s : split) {
                    if (isNumeric(s)){
//                        if (!xNumberList.contains(s) && !oldXNumberList.contains(s) && s.length() == 11){
//                            xNumberList.add(s);
//                        }
                        s = s.substring(0, prefixLength);
                        newList.add(s);
                    }
                }
                break;
            }
            if (isNumeric(line)) {
//                if (!xNumberList.contains(line) && !oldXNumberList.contains(line) && line.length() == 11){
//                    xNumberList.add(line);
//                }
                line = line.substring(0, prefixLength);
                newList.add(line);
            }
        }
//        //添加白名单号码
//        if (xNumberList != null && xNumberList.size() > 0){
//            endMapper.addXNumber(params.getId(),xNumberList);
//        }
        //3.合并两个集合，去重，然后判断集合长度是否增加
        int oldSize = oldList.size();
        oldList.addAll(newList);
        if (oldList.size() == oldSize) {
            //3.1 长度不增加，直接返回“这批白名单已全部添加过”
            return Result.setSuccess(HttpStatus.SUCCESS, "这批白名单已全部添加过");
        } else {
            //3.2 长度增加，处理集合
            StringJoiner sj = new StringJoiner(",");
            if (oldList.size() <= 100) {
                //3.2.1 长度小于等于100，先对集合元素进行排序，然后合并成字符串，填入数据库
                List<String> list = new ArrayList<>(oldList);
                Collections.sort(list);
                for (String s : list) {
                    sj.add(s);
                }
                params.setWhiteNumber(sj.toString());
                int i = endMapper.updateEnd(params);
                if (i > 0) {
                    return Result.setSuccess(HttpStatus.SUCCESS, "白名单已更新");
                } else {
                    return Result.setFail(HttpStatus.FAIL, "白名单更新失败");
                }
            } else {
                //3.2.2 长度大于100，将前缀长度减1，重新处理集合并去重，填入数据库，同时返回“前缀长度已做调整”
                Set<String> newSet = new HashSet<>();
                prefixLength--;
                for (String s : oldList) {
                    newSet.add(s.substring(0, prefixLength));
                }
                List<String> list = new ArrayList<>(newSet);
                Collections.sort(list);
                for (String s : list) {
                    sj.add(s);
                }
                params.setWhiteNumber(sj.toString());
                int i = endMapper.updateEnd(params);
                if (i > 0) {
                    return Result.setSuccess(HttpStatus.SUCCESS, "白名单已更新,前缀长度已做调整");
                } else {
                    return Result.setFail(HttpStatus.FAIL, "白名单更新失败");
                }
            }
        }
    }

    /**
     * 查询全部X号码
     *
     * @param params
     * @return
     */
    @Override
    public Result queryAllXNumber(EndParams params) {
        Page<FrontVo> page = new Page<>(params.getPageNum(), params.getPageSize());
        List<NumberVo> numberList = endMapper.queryAllXNumber(page, params);
        //回填公司名
        for (NumberVo numberVo : numberList) {
            List<Integer> endIdList = endMapper.queryXEndId(numberVo.getNumber());
            StringJoiner stringJoiner = new StringJoiner(",");
            for (Integer id : endIdList) {
                EndVo endVo = endMapper.queryOneEnd(id);
                String company = endVo.getCompany();
                stringJoiner.add(company);
            }
            numberVo.setCompany(stringJoiner.toString());
        }
        return Result.setSuccess(HttpStatus.SUCCESS, "", new PageDataInfo(page, numberList));
    }

    /**
     * 更新落地分布
     */
    public void updateFrontDistribution(Integer endId){
        //查询下对接网关信息
        EndVo endVo = endMapper.queryOneEnd(endId);
        //获取号码id集合
        List<Integer> numberIdList = new ArrayList<>();
        if (endVo.getNumberId() != null && !endVo.getNumberId().equals("")) {
            String[] split = endVo.getNumberId().split(",");
            for (String s : split) {
                numberIdList.add(Integer.parseInt(s));
            }
        }
        //查询全部号码
        if (numberMap == null || numberMap.size() == 0) {
            List<NumberVo> numberVoList = frontMapper.queryAllNumberInfo();
            //将号码id作为键，对应的落地id设为值
            numberMap = new HashMap<>();
            for (NumberVo numberVo : numberVoList) {
                numberMap.put(numberVo.getId(), numberVo.getFrontId());
            }
        }
        List<Integer> frontIdList = new ArrayList<>();
        for (Integer numberId : numberIdList) {
            if (numberMap.get(numberId) != null && !frontIdList.contains(numberMap.get(numberId))){
                frontIdList.add(numberMap.get(numberId));
            }
        }
        String frontIdListStr = Transfer.combineList(frontIdList);
        endMapper.updateFrontDistribution(endId,frontIdListStr);
    }
}
